home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / progsrc / v3dt090 / 3dtools.cpp < prev    next >
C/C++ Source or Header  |  1994-11-01  |  21KB  |  1,078 lines

  1. #include <dos.h>
  2. #include <math.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include "3dtools.h"
  6.  
  7. //      3dtools v0.90ß - released 11-01-94
  8. //      C++ 3d engine
  9. //      coded by Voltaire/OTM
  10. //      all source Copyright (C) 1994 Zach Mortensen
  11. //
  12. //      see 3DTOOLS.NFO and OTM-94.NFO for more information
  13.  
  14. world3d world;
  15. viewPoint camera;
  16.  
  17. //////
  18.    //
  19.   //    dotProduct function definition
  20.  //
  21. //////
  22.  
  23.  
  24. int dotProduct(point3d *p1, point3d *p2)
  25. {
  26.     return((int) ((p1->rotoX * p2->rotoX) + (p1->rotoY * p2->rotoY) +
  27.     (p1->rotoZ * p2->rotoZ)));
  28. }
  29.  
  30.  
  31. //////
  32.    //
  33.   //    point3d class definitions
  34.  //
  35. //////
  36.  
  37.  
  38. point3d::point3d()
  39. {
  40. }
  41.  
  42. point3d::point3d(long x, long y, long z)
  43. {
  44.     setTo(x, y, z);
  45. }
  46.  
  47. void point3d::save(FILE *fp)
  48. {
  49.     int numWritten;
  50.  
  51.     pointRec *temp = new pointRec;
  52.  
  53.     temp->localX = localX;
  54.     temp->localY = localY;
  55.     temp->localZ = localZ;
  56.  
  57.     numWritten = fwrite(temp, sizeof(pointRec), 1, fp);
  58.  
  59. }
  60.  
  61. void point3d::load(FILE *fp)
  62. {
  63.     int numRead;
  64.  
  65.     pointRec *temp = new pointRec;
  66.  
  67.     numRead = fread(temp, sizeof(pointRec), 1, fp);
  68.  
  69.     localX = temp->localX;
  70.     localY = temp->localY;
  71.     localZ = temp->localZ;
  72.  
  73.     rotoX = localX;
  74.     rotoY = localY;
  75.     rotoZ = localZ;
  76. }
  77.  
  78. void point3d::setTo(long x, long y, long z)
  79. {
  80.     x3d = x;
  81.     y3d = y;
  82.     z3d = z;
  83.  
  84.     localX = x;
  85.     localY = y;
  86.     localZ = z;
  87.  
  88.     rotoX = x;
  89.     rotoY = y;
  90.     rotoZ = z;
  91.  
  92.     oX = 0;
  93.     oY = 0;
  94.     oZ = 0;
  95.  
  96.     xDeg = 0;
  97.     yDeg = 0;
  98.     zDeg = 0;
  99.  
  100.     // spherical schtuff
  101. /*
  102.     lRho = (long) sqrt(localX * localX + localY * localY + localZ * localZ);
  103.  
  104.     if (localZ == 0)
  105.     lTheta = (long) 180 * atan(localX) / PI;
  106.     else
  107.     lTheta = (long) 180 * atan(localX / localZ) / PI;
  108.  
  109.     if (lRho == 0)
  110.     lPhi = 0;
  111.     else
  112.     lPhi = (long) 180 * acos(localY / lRho) / PI;
  113.  
  114.     gRho = lRho;
  115.     gTheta = lTheta;
  116.     gPhi = lPhi;
  117. */
  118.     zeroNormal();
  119.  
  120.     xform2d();
  121. }
  122.  
  123. //      project the point to the screen
  124.  
  125. void point3d::xform2d()
  126. {
  127.     if (z3d > 0)
  128.     {
  129.     x2d = ((x3d << 10) / z3d) + 159;
  130.     y2d = 99 - ((y3d << 10) / z3d);
  131.     }
  132.     else
  133.     {
  134.     x2d = x3d;
  135.     y2d = y3d;
  136.     }
  137. }
  138.  
  139. void point3d::display(int color)
  140. {
  141.     setPixel((int) x2d, (int) y2d, color);
  142. }
  143.  
  144. //      set new origin coordinates
  145.  
  146. void point3d::setNewOrigin(point3d *p)
  147. {
  148.     oX = p->x3d;
  149.     oY = p->y3d;
  150.     oZ = p->z3d;
  151.  
  152.     localX = x3d - oX;
  153.     localY = y3d - oY;
  154.     localZ = z3d - oZ;
  155.  
  156.     rotoX = localX;
  157.     rotoY = localY;
  158.     rotoZ = localZ;
  159.  
  160. }
  161.  
  162. //      set new origin, retaining old local coordinates
  163.  
  164. void point3d::globalXform2origin(point3d *p)
  165. {
  166.     oX = p->x3d;
  167.     oY = p->y3d;
  168.     oZ = p->z3d;
  169.  
  170.     globalXform();
  171. /*
  172.     gRho = (long) sqrt(x3d * x3d + y3d * y3d + z3d * z3d);
  173.     if (z3d == 0)
  174.     gTheta = (long) 180 * atan(x3d) / PI;
  175.     else
  176.     gTheta = (long) 180 * atan(x3d / z3d) / PI;
  177.  
  178.     if (gRho == 0)
  179.     gPhi = 0;
  180.     else
  181.     gPhi = (long) 180 * acos(y3d / gRho) / PI;
  182. */
  183. }
  184.  
  185. //      copy origin coordinates from another point
  186.  
  187. void point3d::copyOrigin(point3d *p)
  188. {
  189.     oX = p->oX;
  190.     oY = p->oY;
  191.     oZ = p->oZ;
  192.  
  193.     globalXform();
  194. }
  195.  
  196. /*
  197. void point3d::localRotate(int dTheta, int dPhi)
  198. {
  199.  
  200.     lTheta += dTheta;
  201.     lPhi += dPhi;
  202.  
  203.     rotoX = (lRho * sin(lPhi * PI / 180) * cos(lTheta * PI / 180));
  204.     rotoY = (lRho * cos(lPhi * PI / 180));
  205.     rotoZ = (lRho * sin(lPhi * PI / 180) * sin(lTheta * PI / 180));
  206.  
  207.     globalXform();
  208.  
  209. }
  210. */
  211.  
  212. //      rotate a point about its origin (slow method)
  213.  
  214. void point3d::localRotate(int tX, int tY, int tZ)
  215. {
  216.     int cosX, sinX, cosY, sinY, cosZ, sinZ;
  217.  
  218.     xDeg += tX;
  219.     yDeg += tY;
  220.     zDeg += tZ;
  221.  
  222.     cosX = zDCos(xDeg);
  223.     sinX = zDSin(xDeg);
  224.     cosY = zDCos(yDeg);
  225.     sinY = zDSin(yDeg);
  226.     cosZ = zDCos(zDeg);
  227.     sinZ = zDSin(zDeg);
  228.  
  229.     // Z axis rotation first
  230.     i = (long) ((localX * cosZ - localY * sinZ) >> 16);
  231.     j = (long) ((localX * sinZ + localY * cosZ) >> 16);
  232.     k = (long) localZ;
  233.  
  234.     // now X axis rotation
  235.     rotoY = (long) ((j * cosX - k * sinX) >> 16);
  236.     rotoZ = (long) ((j * sinX + k * cosX) >> 16);
  237.     k = (long) rotoZ;
  238.  
  239.     // now Y axis
  240.     rotoX = (long) ((k * sinY + i * cosY) >> 16);
  241.     rotoZ = (long) ((k * cosY - i * sinY) >> 16);
  242.  
  243.     globalXform();
  244. }
  245.  
  246. //      rotate a point about its origin (faster method, *trig array 
  247. //      used to store sin/cos data that remains constant for all
  248. //      points in a given object
  249.  
  250. void point3d::localRotate(int *trig)
  251. {
  252.     // Z axis rotation first
  253.     i = ((localX * trig[5] - localY * trig[4]) >> 16);
  254.     j = ((localX * trig[4] + localY * trig[5]) >> 16);
  255.     k = localZ;
  256.  
  257.     // now X axis rotation
  258.     rotoY = ((j * trig[1] - k * trig[0]) >> 16);
  259.     rotoZ = ((j * trig[0] + k * trig[1]) >> 16);
  260.     k = rotoZ;
  261.  
  262.     // now Y axis
  263.     rotoX = ((k * trig[2] + i * trig[3]) >> 16);
  264.     rotoZ = ((k * trig[3] - i * trig[2]) >> 16);
  265.  
  266.     globalXform();
  267.  
  268. }
  269.  
  270. //      rotate a point about THE (0, 0, 0) origin
  271.  
  272. void point3d::globalRotate(int *trig)
  273. {
  274.     // Z axis rotation first
  275.     i = (long) ((x3d * trig[5] - y3d * trig[4]) >> 16);
  276.     j = (long) ((x3d * trig[4] + y3d * trig[5]) >> 16);
  277.     k = (long) z3d;
  278.  
  279.     // now X axis rotation
  280.     y3d = (long) ((j * trig[1] - k * trig[0]) >> 16);
  281.     z3d = (long) ((j * trig[0] + k * trig[1]) >> 16);
  282.     k = (long) z3d;
  283.  
  284.     // now Y axis
  285.     x3d = (long) ((k * trig[2] + i * trig[3]) >> 16);
  286.     z3d = (long) ((k * trig[3] - i * trig[2]) >> 16);
  287.  
  288. }
  289.  
  290. //      translate (move) a point by (dX, dY, dZ)
  291.  
  292. void point3d::translate(long dX, long dY, long dZ)
  293. {
  294.     oX += dX;
  295.     oY += dY;
  296.     oZ += dZ;
  297.  
  298.     globalXform();
  299. }
  300.  
  301. //      transform local coordinates to global (world) coordinates
  302.  
  303. void point3d::globalXform()
  304. {
  305.     x3d = rotoX + oX;
  306.     y3d = rotoY + oY;
  307.     z3d = rotoZ + oZ;
  308.  
  309.     xform2d();
  310. }
  311.  
  312. //      zero the normal for this point (used for gouraud shading)
  313.  
  314. void point3d::zeroNormal()
  315. {
  316.     nX = 0;
  317.     nY = 0;
  318.     nZ = 0;
  319.     nCount = 0;
  320. }
  321.  
  322. //      add (dX, dY, dZ) to the normal for this point
  323.  
  324. void point3d::addNormal(int dX, int dY, int dZ)
  325. {
  326.     nX += dX;
  327.     nY += dY;
  328.     nZ += dZ;
  329.     nCount ++;
  330. }
  331.  
  332. //      average the normal of this point
  333.  
  334. void point3d::avgNormal()
  335. {
  336.     long d;
  337.  
  338.     if (nCount)
  339.     {
  340.  
  341.     nX /= nCount;
  342.     nY /= nCount;
  343.     nZ /= nCount;
  344.  
  345.     d = (long) sqrt(nX * nX + nY * nY + nZ * nZ);
  346.  
  347.     nX = (32768 * nX) / d;
  348.     nY = (32768 * nY) / d;
  349.     nZ = (32768 * nZ) / d;
  350.  
  351.     }
  352.  
  353. }
  354.  
  355. point3d::~point3d()
  356. {
  357. }
  358.  
  359.  
  360. //////
  361.    //
  362.   //    line3d class definitions
  363.  //
  364. //////
  365.  
  366. //      NOTE - I don't really know why I included the line3d object,
  367. //      I never really use it anyway.  Most of it is undoubtedly full
  368. //      of bugs...
  369.  
  370. line3d::line3d(point3d *p1, point3d *p2, int c)
  371. {
  372.     point1 = p1;
  373.     point2 = p2;
  374.     calcVectors();
  375.     color = c;
  376.     flag = 0;
  377. }
  378.  
  379. line3d::line3d(long x1, long y1, long z1, long x2, long y2, long z2, int c)
  380. {
  381.     point1 = new point3d(x1, y1, z1);
  382.     point2 = new point3d(x2, y2, z2);
  383.     calcVectors();
  384.     color = c;
  385.     flag = 1;
  386. }
  387.  
  388. void line3d::draw()
  389. {
  390.     // draw_line(point1->x2d, point1->y2d, point2->x2d, point2->y2d, color);
  391. }
  392.  
  393. void line3d::calcVectors()
  394. {
  395.     i = (point1->x3d - point2->x3d);
  396.     j = (point1->y3d - point2->y3d);
  397.     k = (point1->z3d - point2->z3d);
  398. }
  399.  
  400. long line3d::xOfT(double t)
  401. {
  402.     return((long) (point1->x3d + (t * i)));
  403. }
  404.  
  405. long line3d::yOfT(double t)
  406. {
  407.     return((long) (point1->y3d + (t * j)));
  408. }
  409.  
  410. long line3d::zOfT(double t)
  411. {
  412.     return((long) (point1->z3d + (t * k)));
  413. }
  414.  
  415. double line3d::tOfX(long x)
  416. {
  417.     return((i == 0 ? 0 : (x - point1->x3d) / i));
  418. }
  419.  
  420. double line3d::tOfY(long y)
  421. {
  422.     return((j == 0 ? 0 : (y - point1->y3d) / j));
  423. }
  424.  
  425. double line3d::tOfZ(long z)
  426. {
  427.     return((k == 0 ? 0 : (z - point1->z3d) / k));
  428. }
  429.  
  430. void line3d::localRotate(double tX, double tY, double tZ)
  431. {
  432.     point1->localRotate(tX, tY, tZ);
  433.     point2->localRotate(tX, tY, tZ);
  434.     calcVectors();
  435. }
  436.  
  437. line3d::~line3d()
  438. {
  439.     if (flag)
  440.     {
  441.     delete point1;
  442.     delete point2;
  443.     }
  444. }
  445.  
  446.  
  447. //////
  448.    //
  449.   //    polygon class definitions
  450.  //
  451. //////
  452.  
  453. //      These are all triangles BTW
  454.  
  455. polygon::polygon()
  456. {
  457. }
  458.  
  459. polygon::polygon(point3d *v1, point3d *v2, point3d *v3, int c)
  460. {
  461.     setColor(c);
  462.     normal = new point3d;
  463.     setTo(v1, v2, v3);
  464.     shading = sNone;
  465.     facing = fBoth;
  466. }
  467.  
  468. polygon::polygon(point3d *v1, point3d *v2, point3d *v3, point3d *norm, int c)
  469. {
  470.     setColor(c);
  471.  
  472.     p1 = v1;
  473.     p2 = v2;
  474.     p3 = v3;
  475.  
  476.     normal = norm;
  477.  
  478.     line = new line3d* [3];
  479.     line[0] = new line3d(p1, p2, color);
  480.     line[1] = new line3d(p2, p3, color);
  481.     line[2] = new line3d(p3, p1, color);
  482.  
  483. }
  484.  
  485. void polygon::setTo(point3d *v1, point3d *v2, point3d *v3)
  486. {
  487.     float i, j, k, d;
  488.  
  489.     p1 = v1;
  490.     p2 = v2;
  491.     p3 = v3;
  492.  
  493.     i = (float) (((p2->localY - p1->localY) * (p3->localZ - p1->localZ)) -
  494.         ((p2->localZ - p1->localZ) * (p3->localY - p1->localY)));
  495.  
  496.     j = (float) (((p2->localZ - p1->localZ) * (p3->localX - p1->localX)) -
  497.         ((p2->localX - p1->localX) * (p3->localZ - p1->localZ)));
  498.  
  499.     k = (float) (((p2->localX - p1->localX) * (p3->localY - p1->localY)) -
  500.         ((p2->localY - p1->localY) * (p3->localX - p1->localX)));
  501.  
  502.     d = (float) sqrt((double) ((i * i) + (j * j) + (k * k)));
  503.  
  504.     i = (float) (i / d * 32767);
  505.     j = (float) (j / d * 32767);
  506.     k = (float) (k / d * 32767);
  507.  
  508.     normal->setTo((long) i, (long) j, (long) k);
  509.     normal->copyOrigin(p1);
  510.  
  511.     line = new line3d* [3];
  512.     line[0] = new line3d(p1, p2, color);
  513.     line[1] = new line3d(p2, p3, color);
  514.     line[2] = new line3d(p3, p1, color);
  515.  
  516. }
  517.  
  518. //      average Z value of a polygon, used for depth sorting
  519.  
  520. long polygon::avgZ()
  521. {
  522.     return((long) ((p1->z3d + p2->z3d + p3->z3d) / 3));
  523. }
  524.  
  525. void polygon::setColor(int c)
  526. {
  527.     color = c;
  528. }
  529.  
  530. void polygon::wireFrame()
  531. {
  532.     for (count = 0; count < 3; count++)
  533.     line[count]->draw();
  534. }
  535.  
  536. void polygon::paintSolid()
  537. {
  538.     //dot = dotProduct(normal, camera.view);
  539.     //if (dot < 0)
  540.     if (shading)
  541.     dot = -(dotProduct(normal, camera.light));
  542.  
  543.     poly3(p1->x2d, p1->y2d, p2->x2d, p2->y2d, p3->x2d, p3->y2d,
  544.     color + (dot >> 11));
  545.  
  546.     // NOTE:  dot >> 11 = (dot / 32767 * 16) = cos T * 16 = offset into
  547.     // block of 16 colors
  548.  
  549. }
  550.  
  551. void polygon::setNewOrigin(point3d *p)
  552. {
  553.     p1->setNewOrigin(p);
  554.     p2->setNewOrigin(p);
  555.     p3->setNewOrigin(p);
  556.     normal->setNewOrigin(p);
  557. }
  558.  
  559. //      this function should be called for all polygons in an object,
  560. //      following which point->avgNormals() should be called for all
  561. //      points in an object.  The obj3d->setGNormals function takes
  562. //      care of all of this...
  563.  
  564. void polygon::setGNormals()
  565. {
  566.     p1->addNormal(normal->rotoX, normal->rotoY, normal->rotoZ);
  567.     p2->addNormal(normal->rotoX, normal->rotoY, normal->rotoZ);
  568.     p3->addNormal(normal->rotoX, normal->rotoY, normal->rotoZ);
  569. }
  570.  
  571. void polygon::gShade()
  572. {
  573.     int dot1, dot2, dot3;
  574.  
  575.     //dot = dotProduct(normal, camera.view);
  576.     //if (dot < 0)
  577.     //{
  578.     dot1 = abs(dotProduct((point3d *) p1->normal, camera.light));
  579.     dot2 = abs(dotProduct((point3d *) p2->normal, camera.light));
  580.     dot3 = abs(dotProduct((point3d *) p3->normal, camera.light));
  581.     gpoly3(p1->x2d, p1->y2d, color + (dot1 >> 11),
  582.            p2->x2d, p2->y2d, color + (dot2 >> 11),
  583.            p3->x2d, p3->y2d, color + (dot3 >> 11));
  584.     //}
  585. }
  586.  
  587. void polygon::setShading(int shade)
  588. {
  589.     shading = shade;
  590. }
  591.  
  592. void polygon::setFacing(int face)
  593. {
  594.     facing = face;
  595. }
  596.  
  597. //      display a polygon according to the set shading and facing data
  598.  
  599. void polygon::display()
  600. {
  601.     if (shading)
  602.     {
  603.     if (facing)
  604.     {
  605.         dot = dotProduct(normal, camera.view);
  606.         if (facing == fInside)
  607.         dot = -dot;
  608.  
  609.         if (dot < 0)
  610.         {
  611.         if (shading == sGouraud)
  612.             gShade();
  613.         else
  614.             paintSolid();
  615.         }
  616.  
  617.     }
  618.     else
  619.     {
  620.         if (shading == sGouraud)
  621.         gShade();
  622.         else
  623.         paintSolid();
  624.     }
  625.     }
  626.     else
  627.     {
  628.     if (facing)
  629.     {
  630.         dot = dotProduct(normal, camera.view);
  631.         if (facing == fInside)
  632.         dot = -dot;
  633.  
  634.         if (dot < 0)
  635.         {
  636.         dot = 0;
  637.         paintSolid();
  638.         }
  639.     }
  640.     else
  641.     {
  642.         dot = 0;
  643.         paintSolid();
  644.     }
  645.     }
  646.  
  647. }
  648.  
  649. polygon::~polygon()
  650. {
  651.     for (count = 0; count < 3; count++)
  652.     delete line[count];
  653.     delete line;
  654.     delete normal;
  655. }
  656.  
  657.  
  658. //////
  659.    //
  660.   //    obj3d class definitions
  661.  //
  662. //////
  663.  
  664.  
  665. obj3d::obj3d(long x, long y, long z)
  666. {
  667.     origin = new point3d(x, y, z);
  668.  
  669.     numPoints = 0;
  670.     numPolys = 0;
  671.  
  672.     point = new point3d* [1];
  673.     poly = new polygon* [1];
  674.  
  675.     trig = new int [6];
  676.  
  677.     xDeg = 0;
  678.     yDeg = 0;
  679.     zDeg = 0;
  680.  
  681. }
  682.  
  683. //      the save and load functions are out of date.  If you wish, you may
  684. //      rewrite them...
  685.  
  686. void obj3d::save(FILE *fp)
  687. {
  688.     int numWritten, count2;
  689.  
  690.     polyRec *pRec = new polyRec;
  691.     objFileHeader *header = new objFileHeader;
  692.  
  693.     // assumes fp has already been opened, so we can store multiple objects
  694.     // in the same file
  695.  
  696.     header->numPoints = numPoints;
  697.     header->numPolys = numPolys;
  698.  
  699.     numWritten = fwrite(header, sizeof(objFileHeader), 1, fp);
  700.  
  701.     for (count = 0; count < numPoints; count++)
  702.     point[count]->save(fp);
  703.  
  704.     for (count2 = 0; count2 < numPolys; count2++)
  705.     {
  706.     pRec->p1 = getPointNum(poly[count2]->p1);
  707.     pRec->p2 = getPointNum(poly[count2]->p2);
  708.     pRec->p3 = getPointNum(poly[count2]->p3);
  709.     pRec->normal = getPointNum(poly[count2]->normal);
  710.     pRec->color = poly[count2]->color;
  711.  
  712.     numWritten = fwrite(pRec, sizeof(polyRec), 1, fp);
  713.  
  714.     }
  715.  
  716. }
  717.  
  718. void obj3d::load(FILE *fp)
  719. {
  720.     int numRead;
  721.  
  722.     polyRec *pRec = new polyRec;
  723.     objFileHeader *header = new objFileHeader;
  724.  
  725.     // free old data
  726.  
  727.     for (count = 0; count < numPoints; count++)
  728.     delete point[count];
  729.  
  730.     for (count = 0; count < numPolys; count++)
  731.     delete point[count];
  732.  
  733.     // assumes fp has already been opened, so we can store multiple objects
  734.     // in the same file
  735.  
  736.     numRead = fread(header, sizeof(objFileHeader), 1, fp);
  737.  
  738.     numPoints = header->numPoints;
  739.     numPolys = header->numPolys;
  740.  
  741.     for (count = 0; count < numPoints; count++)
  742.     {
  743.     point[count] = new point3d;
  744.     point[count]->load(fp);
  745.     point[count]->globalXform2origin(origin);
  746.     }
  747.  
  748.     for (count = 0; count < numPolys; count++)
  749.     {
  750.     numRead = fread(pRec, sizeof(polyRec), 1, fp);
  751.  
  752.     poly[count] = new polygon(point[pRec->p1], point[pRec->p2],
  753.         point[pRec->p3], point[pRec->normal], pRec->color);
  754.     }
  755.  
  756.     // nix the old rotations...
  757.  
  758.     xDeg = 0;
  759.     yDeg = 0;
  760.     zDeg = 0;
  761. }
  762.  
  763. //      add a point whose coordinates are given as local to the origin of
  764. //      this object to this objects list of points
  765.  
  766. void obj3d::addLocalPoint(long x, long y, long z)
  767. {
  768.     point3d **temp;
  769.  
  770.     temp = new point3d* [numPoints + 1];
  771.     memcpy(temp, point, numPoints * sizeof(point3d*));
  772.  
  773.     delete point;
  774.     point = temp;
  775.  
  776.     numPoints++;
  777.     point[numPoints - 1] = new point3d(x, y, z);
  778.     point[numPoints - 1]->globalXform2origin(origin);
  779.  
  780. }
  781.  
  782. void obj3d::addLocalPoint(point3d *p)
  783. {
  784.     point3d **temp;
  785.  
  786.     temp = new point3d* [numPoints + 1];
  787.     memcpy(temp, point, numPoints * sizeof(point3d*));
  788.  
  789.     delete point;
  790.     point = temp;
  791.  
  792.     p->globalXform2origin(origin);
  793.     numPoints++;
  794.     point[numPoints - 1] = p;
  795. }
  796.  
  797. //      add a point whose coordinates are given in terms of THE (0,0,0) 
  798. //      origin to this object's list of points
  799.  
  800. void obj3d::addGlobalPoint(long x, long y, long z)
  801. {
  802.     addLocalPoint(x - origin->x3d, y - origin->y3d, z - origin->z3d);
  803. }
  804.  
  805. void obj3d::addGlobalPoint(point3d *p)
  806. {
  807.     p->setNewOrigin(origin);
  808.     addLocalPoint(p);
  809. }
  810.  
  811. //      add a local polygon (whose vertices are local points)
  812.  
  813. void obj3d::addLocalPoly(polygon *pg)
  814. {
  815.     polygon **temp;
  816.  
  817.     temp = new polygon* [numPolys + 1];
  818.     memcpy(temp, poly, numPolys * sizeof(polygon*));
  819.  
  820.     delete poly;
  821.     poly = temp;
  822.  
  823.     numPolys++;
  824.     poly[numPolys - 1] = pg;
  825.     addLocalPoint(pg->normal);
  826. }
  827.  
  828. void obj3d::addLocalPoly(int p1, int p2, int p3, int c)
  829. {
  830.     polygon *pg = new polygon(point[p1], point[p2], point[p3], c);
  831.     addLocalPoly(pg);
  832. }
  833.  
  834. //      add a poly whose vertices are given in global coordinates
  835.  
  836. void obj3d::addGlobalPoly(polygon *pg)
  837. {
  838.     pg->setNewOrigin(origin);
  839.     addLocalPoly(pg);
  840. }
  841.  
  842. int obj3d::getPointNum(long x, long y, long z)
  843. {
  844.     for (count = 0; count < numPoints; count++)
  845.        if (point[count]->localX == x && point[count]->localY == y &&
  846.         point[count]->localZ == z)
  847.         return(count);
  848.  
  849.     // couldn't find it, let's CREATE IT!
  850.     addLocalPoint(x, y, z);
  851.     return(numPoints - 1);
  852. }
  853.  
  854. int obj3d::getPointNum(point3d *p)
  855. {
  856.     for (count = 0; count < numPoints; count++)
  857.     if (point[count] == p)
  858.         return(count);
  859.  
  860.     return(-1);
  861. }
  862.  
  863. //      rotate this object about it's origin
  864.  
  865. void obj3d::localRotate(int tX, int tY, int tZ)
  866. {
  867.     xDeg += tX;
  868.     yDeg += tY;
  869.     zDeg += tZ;
  870.  
  871.     xDeg %= 360;
  872.     yDeg %= 360;
  873.     zDeg %= 360;
  874.  
  875.     trig[0] = zDSin(xDeg);
  876.     trig[1] = zDCos(xDeg);
  877.     trig[2] = zDSin(yDeg);
  878.     trig[3] = zDCos(yDeg);
  879.     trig[4] = zDSin(zDeg);
  880.     trig[5] = zDCos(zDeg);
  881.  
  882.     for (count = 0; count < numPoints; count++)
  883.     point[count]->localRotate(trig);
  884. }
  885.  
  886. /*
  887. void obj3d::localRotate(int dTheta, int dPhi)
  888. {
  889.     for (count = 0; count < numPoints; count++)
  890.     point[count]->localRotate(dTheta, dPhi);
  891. }
  892. */
  893.  
  894. //      translate (move) this object
  895.  
  896. void obj3d::translate(int dX, int dY, int dZ)
  897. {
  898.     origin->translate(dX, dY, dZ);
  899.     for (count = 0; count < numPoints; count++)
  900.         point[count]->translate(dX, dY, dZ);
  901. }
  902.  
  903. //      rotate this object about THE (0,0,0) origin
  904.  
  905. void obj3d::globalRotate(int *trig)
  906. {
  907.     origin->globalRotate(trig);
  908.     for (count  = 0; count < numPoints; count++)
  909.         point[count]->globalRotate(trig);
  910. }
  911.  
  912. //      depth sort this object's planes
  913.  
  914. void obj3d::sortPlanes()
  915. {
  916.     polygon *temp;
  917.     register int pos, index;
  918.  
  919.     for (pos = 0; pos < (numPolys - 1); pos++)
  920.     {
  921.     index = pos;
  922.     for (count = index + 1; count < numPolys; count++)
  923.         if (poly[count]->avgZ() > poly[index]->avgZ())
  924.         index = count;
  925.  
  926.     if (index != pos)
  927.     {
  928.         temp = poly[pos];
  929.         poly[pos] = poly[index];
  930.         poly[index] = temp;
  931.     }
  932.     }
  933.  
  934. }
  935.  
  936. //      display as dots
  937.  
  938. void obj3d::paintDots()
  939. {
  940.     for (count = 0; count < numPoints; count++)
  941.     point[count]->display(15);
  942. }
  943.  
  944. //      display as a wireframe
  945.  
  946. void obj3d::wireFrame()
  947. {
  948.     sortPlanes();
  949.     for (count = 0; count < numPolys; count++)
  950.     poly[count]->wireFrame();
  951. }
  952.  
  953. //      display Lambert (flat) shaded
  954.  
  955. void obj3d::paintSolid()
  956. {
  957.     sortPlanes();
  958.     for (count = 0; count < numPolys; count++)
  959.     poly[count]->paintSolid();
  960. }
  961.  
  962. //      set the location of this object in global coordinates
  963.  
  964. void obj3d::setLocation(long x, long y, long z)
  965. {
  966.     origin->setTo(x, y, z);
  967.     for (count = 0; count < numPoints; count++)
  968.     point[count]->setNewOrigin(origin);
  969. }
  970.  
  971. //      have this object set up its normal vectors needed for gouraud shading
  972.  
  973. void obj3d::setGNormals()
  974. {
  975.     int temp;
  976.  
  977.     for (count = 0; count < numPolys; count++)
  978.     poly[count]->setGNormals();
  979.  
  980.     for (count = 0; count < numPoints; count++)
  981.     point[count]->avgNormal();
  982.  
  983.     temp = numPoints;
  984.     for (count = 0; count < temp; count++)
  985.     if (point[count]->nCount)
  986.     {
  987.         addLocalPoint(point[count]->nX, point[count]->nY, point[count]->nZ);
  988.         point[count]->normal = (void *) point[numPoints - 1];
  989.     }
  990.  
  991. }
  992.  
  993. //      gouraud shade this object
  994.  
  995. void obj3d::gShade()
  996. {
  997.     sortPlanes();
  998.     for (count = 0; count < numPolys; count++)
  999.     poly[count]->gShade();
  1000.  
  1001. }
  1002.  
  1003. //      universal display function that utilizes each polygon's shading
  1004. //      and facing data.  This allows you to combine gouraud, flat, and
  1005. //      nonshaded polygons in the same object.
  1006.  
  1007. void obj3d::display()
  1008. {
  1009.     sortPlanes();
  1010.     for (count = 0; count < numPolys; count++)
  1011.     poly[count]->display();
  1012. }
  1013.  
  1014. obj3d::~obj3d()
  1015. {
  1016.     for (count = 0; count < numPolys; count++)
  1017.     delete poly[count];
  1018.     for (count = 0; count < numPoints; count++)
  1019.     delete point[count];
  1020.  
  1021.     delete trig;
  1022.     delete poly;
  1023.     delete point;
  1024.     delete origin;
  1025. }
  1026.  
  1027.  
  1028. //      THE WORLD AND VIEWPOINT CLASSES HAVE NOT BEEN FULLY IMPLEMENTED!  If 
  1029. //      you want to use them, rewrite them.  You MUST leave the light and view
  1030. //      vectors in the camera class, though.  They are used for shading and
  1031. //      plane elimination
  1032.  
  1033. //////
  1034.    //
  1035.   //    world3d class definitons
  1036.  //
  1037. //////
  1038.  
  1039.  
  1040. world3d::world3d()
  1041. {
  1042.     object = new obj3d* [MAX_OBJS];
  1043.     numObjs = 0;
  1044. }
  1045.  
  1046. world3d::~world3d()
  1047. {
  1048.     int count;
  1049.  
  1050.     for (count = 0; count < numObjs; count++)
  1051.     delete object[count];
  1052.  
  1053.     delete object;
  1054. }
  1055.  
  1056.  
  1057. //////
  1058.    //
  1059.   //    viewPoint class definitions
  1060.  //
  1061. //////
  1062.  
  1063.  
  1064. viewPoint::viewPoint()
  1065. {
  1066.     location = new point3d(0, 0, 0);
  1067.     light = new point3d(0, 0, 1);
  1068.     view = new point3d(0, 0, 1);
  1069. }
  1070.  
  1071. viewPoint::~viewPoint()
  1072. {
  1073.     delete location;
  1074.     delete light;
  1075.     delete view;
  1076. }
  1077.  
  1078.